<template>
  <div class="basic-card flex ">
    <ul class="nav">
      <li v-for="item in catalogList" :key="item.name" :class="{'active': activeCatalog === item.name}" @click="goAnchor(item.name)">{{ item.label }}</li>
    </ul>
    <div class="box-container">
      <el-form :model="form" label-width="180px" class="corp-form" @scroll.native="handleScroll">
        <div v-for="item in catalogList" :key="item.name" class="box">
          <div :class="['title', item.name]">{{ item.title }}</div>
          <div class="content">
            <div v-for="attr in item.items" :key="attr.id">
              <el-form-item :label="attr.label">
                <template v-if="['audio', 'field'].includes(attr.type)">
                  <el-input :value="item.formData[attr.key]" disabled class="input" />
                </template>
                <template v-else-if="['select', 'multipleSelect'].includes(attr.type)">
                  <el-select
                    :value="attr.type === 'multipleSelect' ? item.formData[attr.key].split(',') : item.formData[attr.key]"
                    :multiple="attr.type === 'multipleSelect'"
                    class="input"
                    style="width: 400px"
                    disabled
                  >
                    <el-option
                      v-for="option in dict.type[attr.dictType]"
                      :key="option.key"
                      :label="option.key"
                      :value="option.value"
                    />
                  </el-select>
                </template>
                <template v-else-if="['date', 'time', 'datetime', 'year-month'].includes(attr.type)">
                  <el-date-picker
                    :value="item.formData[attr.key]"
                    disabled
                    :type="attr.type"
                    format="yyyy年MM月dd日"
                    class="input"
                  />
                </template>
                <template v-else-if="['radio'].includes(attr.type)">
                  <el-radio-group :value="item.formData[attr.key]" disabled>
                    <el-radio v-for="option in dict.type[attr.dictType]" :key="option.value" :label="option.value">{{ item.label }}</el-radio>
                  </el-radio-group>
                </template>
                <template v-else-if="['checkbox'].includes(attr.type)">
                  <el-checkbox-group :value="item.formData[attr.key]" disabled>
                    <el-checkbox v-for="option in dict.type[attr.dictType]" :key="option.value" :name="option.value">{{ item.label }}</el-checkbox>
                  </el-checkbox-group>
                </template>
                <template v-else-if="['uploader'].includes(attr.type)">
                  <el-upload
                    list-type="picture-card"
                    action="#"
                    multiple
                    disabled
                    :file-list="item.formData[attr.key]"
                    :auto-upload="false"
                    :on-preview="previewFile"
                  >
                    <i class="el-icon-plus" />
                  </el-upload>
                </template>
                <template v-else-if="['sign'].includes(attr.type)">
                  <img :src="item.formData[attr.key].url" class="img-sign">
                </template>
                <template v-else-if="['table'].includes(attr.type)">
                  <table style="width: 1200px">
                    <thead>
                      <tr>
                        <th v-for="option in attr.columnClasses" :key="option.id">{{ option.label }}</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(option, index) in attr.value" :key="index">
                        <th v-for="col in attr.columnClasses" :key="col.id">
                          <template v-if="['select'].includes(col.type)">
                            <el-select
                              :value="option[col.key]"
                              class="input"
                              style="width: 400px"
                              disabled
                            >
                              <el-option
                                v-for="v in dict.type[col.dictType]"
                                :key="v.key"
                                :label="v.key"
                                :value="v.value"
                              />
                            </el-select>
                          </template>
                          <template v-else-if="['uploader'].includes(col.type)">
                            <el-upload
                              list-type="picture-card"
                              action="#"
                              multiple
                              disabled
                              :file-list="option[col.key]"
                              :auto-upload="false"
                              :on-preview="previewFile"
                            >
                              <i class="el-icon-plus" />
                            </el-upload>
                          </template>
                          <span v-else>{{ option[col.key] }}</span>
                        </th>
                      </tr>
                    </tbody>
                  </table>
                </template>
              </el-form-item>
            </div>
          </div>
        </div>
      </el-form>
    </div>
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
import { saveAs } from 'file-saver'
import { isImage } from '@/utils'
import { listData } from '@/api/system/dict/data'

export default {
  name: 'BasicCard',
  props: {
    info: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      dict: {},
      form: {},
      catalogList: [],
      clicked: false,
      activeCatalog: '',
      anchorOffsetMap: {}, // 锚点从上到下的offsetTop数据
      dialogVisible: false,
      dialogImageUrl: ''
    }
  },
  watch: {
    info: {
      immediate: true,
      handler: function(val) {
        val.metrics && this.initData()
      }
    }
  },
  methods: {
    async initData() {
      const metrics = this.info.metrics
      // 获取字典keys，并填充defaultValue
      const dicts = []
      metrics.forEach(catalog => {
        const formData = {}
        catalog.items.forEach(item => {
          item.value = item.value || item.defaultValue
          formData[item.key] = item.value
          // if (item.type === 'audio') catalog.hasAudio = true
          if (['select', 'multipleSelect'].includes(item.type) && !dicts.includes(item.dictType)) {
            dicts.push(item.dictType)
          } else if (item.type === 'table') {
            item.columnClasses.forEach(v => {
              if (['select', 'multipleSelect'].includes(v.type) && !dicts.includes(v.dictType)) {
                dicts.push(v.dictType)
              }
            })
          }

          if (['uploader', 'sign', 'table'].includes(item.type) && item.value) {
            item.value = JSON.parse(item.value)
            formData[item.key] = item.value
          }
        })
        catalog.formData = formData
      })
      await this.getDict(dicts)
      this.catalogList = metrics
      this.activeCatalog = metrics[0].name
      setTimeout(this.initAnchorData, 100)
    },
    getDict(dicts) {
      return new Promise((resolve) => {
        const dict = {
          type: {},
          label: {}
        }
        dicts.forEach(async dictType => {
          const { rows } = await listData({
            pageNum: 1,
            pageSize: 10,
            dictType
          })
          const labelMap = {}
          dict.type[dictType] = rows.map(row => {
            labelMap[row.dictValue] = {
              label: row.dictLabel,
              color: { info: '#909399', primary: '#409eff', success: '#67c23a', danger: '#f56c6c', warning: '#e6a23c' }[row.listClass]
            }

            return {
              text: row.dictLabel,
              label: row.dictLabel,
              value: row.dictValue
            }
          })
          dict.label[dictType] = labelMap
          if (Object.keys(dict.type).length === dicts.length) {
            this.dict = dict
            resolve(dict)
          }
        })
      })
    },
    // 初始化anchor高度
    initAnchorData() {
      this.catalogList.forEach(catalog => {
        this.anchorOffsetMap[catalog.name] = document.querySelector(`.${catalog.name}`) ? document.querySelector(`.${catalog.name}`).offsetTop : 0
      })
    },

    goAnchor(catalog) {
      this.clicked = true
      this.activeCatalog = catalog
      const el = document.querySelector('.corp-form')
      el.scrollTo({
        top: this.anchorOffsetMap[catalog] - 5,
        behavior: 'smooth'
      })
    },
    handleScroll(e) {
      const top = e.target.scrollTop
      let active = null
      this.catalogList.forEach(item => {
        if (top + 100 >= this.anchorOffsetMap[item.name]) {
          active = item.name
        }
      })
      if (this.clicked) {
        setTimeout(() => { this.clicked = false }, 1100)
      } else {
        this.activeCatalog = active
      }
    },

    handleItemsChange(type, data) {
      this.form[type] = data
      this.initAnchorData()
    },
    handleChange(data) {
      this.form = data
      this.initAnchorData()
    },
    previewFile(file) {
      if (file.raw) {
        if (file.raw.type.includes('image')) {
          const url = this.getFileBlobUrl(file.raw)
          this.dialogImageUrl = url
          this.dialogVisible = true
        } else {
          saveAs(file.raw)
        }
      } else if (isImage(file.url.split('.').pop())) {
        this.dialogImageUrl = file.url
        this.dialogVisible = true
      } else {
        saveAs(file.url)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";

.basic-card {
  height: 100%;
  overflow: hidden;
  background-color: #fff;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border-right: 1px solid $border-color;
  overflow: auto;
  flex-shrink: 0;
  li {
      padding: 10px 12px;
      white-space: nowrap;
      cursor: pointer;
      &.active {
        color: $primary-color;
        border-left: 3px $primary-color;
        box-shadow: -1px 0 $primary-color;
      }
    }
}
.box-container {
  display: flex;
  flex-direction: column;
  flex-grow: 2;
  padding-top: 10px;
}
.corp-form {
  margin-left: 20px;
  flex-grow: 2;
  overflow: auto;
}
.box {
  .title {
    position: relative;
    font-size: 14px;
    color: $label-color;
    line-height: 26px;
    padding-left: 10px;
    margin: 0 0 10px;
    text-align: initial;
    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 3px;
      bottom: 0;
      width: 3px;
      background-color: $primary-color;
      border-radius: 3px;
    }
  }
}
.img-sign {
  width: 100px;
  height: 50px;
}
</style>
